package com.khaled.protclass.server.ui;


import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;

import javax.swing.ButtonGroup;
import javax.swing.DefaultComboBoxModel;
import javax.swing.GroupLayout;
import javax.swing.GroupLayout.Alignment;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.JRadioButton;
import javax.swing.JScrollPane;
import javax.swing.JTabbedPane;
import javax.swing.JTable;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.LayoutStyle.ComponentPlacement;
import javax.swing.ListSelectionModel;
import javax.swing.SwingConstants;
import javax.swing.border.EmptyBorder;
import javax.swing.border.EtchedBorder;
import javax.swing.filechooser.FileFilter;
import javax.swing.table.DefaultTableModel;

import com.khaled.protclass.model.bean.prediction.PredictionForm;
import com.khaled.protclass.model.bean.prediction.PredictionResult;
import com.khaled.protclass.model.prediction.Prediction;
import com.khaled.protclass.model.util.UtilDirectory;
import com.khaled.protclass.server.bean.RequestForm;
import com.khaled.protclass.server.common.Configuration;

public class VirulentCD extends JFrame
{

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;

	private JPanel contentPane;

	private JTextField txtFastaFile;

	private ButtonGroup group;

	private JTextField txtBlastPath;

	private JTable table;

	private JTextArea proteins_paste = new JTextArea();

	private JPanel tab_Prediction = new JPanel();

	private DefaultTableModel tableModel;

	private JTextField txtNRDB;

	/**
	 * Launch the application.
	 */
	public static void main(String[] args)
	{
		EventQueue.invokeLater(new Runnable()
		{
			public void run()
			{
				try
				{
					VirulentCD frame = new VirulentCD();
					frame.setVisible(true);
				}
				catch (Exception e)
				{
					e.printStackTrace();
				}
			}
		});
	}

	/**
	 * Create the frame.
	 */
	public VirulentCD()
	{
		setResizable(false);
		setTitle("Virulent-CD: Prediction of prokaryotic virulent proteins");
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		setBounds(100, 100, 683, 560);
		contentPane = new JPanel();
		contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
		contentPane.setLayout(new BorderLayout(0, 0));
		setContentPane(contentPane);

		final JTabbedPane tabbedPane = new JTabbedPane(JTabbedPane.TOP);
		tabbedPane.setTabLayoutPolicy(JTabbedPane.SCROLL_TAB_LAYOUT);
		contentPane.add(tabbedPane, BorderLayout.CENTER);

		JPanel panel_6 = new JPanel();
		panel_6.setBackground(Color.WHITE);
		tabbedPane.addTab("Home", null, panel_6, null);

		JPanel panel_8 = new JPanel();
		panel_8.setBackground(Color.WHITE);
		panel_8.setBorder(new EtchedBorder(EtchedBorder.LOWERED, Color.LIGHT_GRAY, Color.GREEN));

		JLabel lblNewLabel_2 = new JLabel("Introduction");
		lblNewLabel_2.setFont(new Font("Tahoma", Font.BOLD, 30));

		JLabel lblCitation = new JLabel("Citation");
		lblCitation.setFont(new Font("Tahoma", Font.BOLD, 30));

		JTextArea txtrVirulentcdIsA = new JTextArea();
		txtrVirulentcdIsA.setEditable(false);
		txtrVirulentcdIsA.setForeground(Color.BLACK);
		txtrVirulentcdIsA.setBackground(Color.WHITE);
		txtrVirulentcdIsA.setFont(new Font("Times New Roman", Font.PLAIN, 15));
		txtrVirulentcdIsA.setLineWrap(true);
		txtrVirulentcdIsA
				.setText("Virulent-CD is a bacterial virulent protein prediction method\r\nPaper Abstract\r\nPaper Abstract\r\nPaper Abstract\r\nPaper Abstract\r\nPaper Abstract\r\nPaper Abstract\r\nPaper Abstract\r\nPaper Abstract");
		GroupLayout gl_panel_6 = new GroupLayout(panel_6);
		gl_panel_6.setHorizontalGroup(gl_panel_6.createParallelGroup(Alignment.LEADING).addGroup(
				gl_panel_6
						.createSequentialGroup()
						.addComponent(panel_8, GroupLayout.PREFERRED_SIZE, 223, GroupLayout.PREFERRED_SIZE)
						.addGroup(
								gl_panel_6
										.createParallelGroup(Alignment.TRAILING)
										.addGroup(
												gl_panel_6
														.createSequentialGroup()
														.addPreferredGap(ComponentPlacement.RELATED)
														.addGroup(
																gl_panel_6
																		.createParallelGroup(Alignment.LEADING)
																		.addComponent(lblNewLabel_2)
																		.addComponent(lblCitation, GroupLayout.PREFERRED_SIZE, 191,
																				GroupLayout.PREFERRED_SIZE)).addContainerGap(242, Short.MAX_VALUE))
										.addGroup(
												gl_panel_6.createSequentialGroup().addPreferredGap(ComponentPlacement.RELATED)
														.addComponent(txtrVirulentcdIsA, GroupLayout.PREFERRED_SIZE, 420, GroupLayout.PREFERRED_SIZE)
														.addContainerGap()))));
		gl_panel_6.setVerticalGroup(gl_panel_6
				.createParallelGroup(Alignment.LEADING)
				.addComponent(panel_8, GroupLayout.DEFAULT_SIZE, 494, Short.MAX_VALUE)
				.addGroup(
						gl_panel_6.createSequentialGroup().addContainerGap().addComponent(lblNewLabel_2)
								.addPreferredGap(ComponentPlacement.RELATED, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
								.addComponent(txtrVirulentcdIsA, GroupLayout.PREFERRED_SIZE, 292, GroupLayout.PREFERRED_SIZE)
								.addPreferredGap(ComponentPlacement.RELATED)
								.addComponent(lblCitation, GroupLayout.PREFERRED_SIZE, 37, GroupLayout.PREFERRED_SIZE).addGap(111)));

		JLabel lblImage = new JLabel("");
		lblImage.setIcon(new ImageIcon("Virulent-CD/virulentcd.png"));
		GroupLayout gl_panel_8 = new GroupLayout(panel_8);
		gl_panel_8.setHorizontalGroup(gl_panel_8.createParallelGroup(Alignment.TRAILING).addGroup(Alignment.LEADING,
				gl_panel_8.createSequentialGroup().addContainerGap().addComponent(lblImage).addContainerGap(16, Short.MAX_VALUE)));
		gl_panel_8.setVerticalGroup(gl_panel_8.createParallelGroup(Alignment.TRAILING).addGroup(
				gl_panel_8.createSequentialGroup().addContainerGap(230, Short.MAX_VALUE).addComponent(lblImage)));
		panel_8.setLayout(gl_panel_8);
		panel_6.setLayout(gl_panel_6);

		JPanel panel = new JPanel();
		tabbedPane.addTab("Configuration", null, panel, null);

		JLabel lblEnterThePath = new JLabel("Enter the path of BLAST program (bin directory):");
		lblEnterThePath.setFont(new Font("Times New Roman", Font.BOLD, 12));

		JPanel panel_7 = new JPanel();
		panel_7.setForeground(Color.GREEN);
		panel_7.setBorder(new EtchedBorder(EtchedBorder.LOWERED, Color.LIGHT_GRAY, Color.GREEN));

		txtBlastPath = new JTextField();
		txtBlastPath.setColumns(10);
		txtBlastPath.setEditable(false);

		txtNRDB = new JTextField();
		txtNRDB.setEditable(false);
		txtNRDB.setColumns(10);

		final JTextField txtCDD_DB = new JTextField();
		txtCDD_DB.setEditable(false);
		txtCDD_DB.setColumns(10);

		JButton button = new JButton("Browse");
		button.setMnemonic('1');
		JButton button_1 = new JButton("Browse");
		button_1.setMnemonic('2');
		JButton button_2 = new JButton("Browse");
		button_2.setMnemonic('3');

		ActionListener blastBrowse = new ActionListener()
		{
			public void actionPerformed(ActionEvent e)
			{
				boolean validBlast = false;
				boolean validNR = false;
				boolean validCDD = false;

				// Create a file chooser
				final JFileChooser fc = new JFileChooser(txtBlastPath.getText().trim());
				fc.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
				int returnVal = fc.showOpenDialog(VirulentCD.this);
				if (returnVal == JFileChooser.APPROVE_OPTION)
				{
					File file = fc.getSelectedFile();

					if (((JButton) e.getSource()).getMnemonic() == 49)
					{
						txtBlastPath.setText(file.getPath());
						if (file.exists())
						{
							validBlast = validateBlastPath(txtBlastPath.getText().trim());
							if (validBlast)
							{
								viewPredictionTab();
							}
							else
							{
								tabbedPane.setEnabledAt(2, false);
							}
						}
						else
						{
							JOptionPane.showMessageDialog(new JFrame(), "The BLAST directory is not exist.", "Error!", JOptionPane.ERROR_MESSAGE);
						}
					}
					if (((JButton) e.getSource()).getMnemonic() == 50)
					{
						txtNRDB.setText(file.getPath());
						if (validDBPath(txtNRDB.getText(), "nr.00"))
						{
							viewPredictionTab();
						}
						else
						{
							tabbedPane.setEnabledAt(2, false);
						}
					}
					if (((JButton) e.getSource()).getMnemonic() == 51)
					{
						txtCDD_DB.setText(file.getPath());
						if (validDBPath(txtCDD_DB.getText(), "Cdd"))
						{
							viewPredictionTab();
						}
						else
						{
							tabbedPane.setEnabledAt(2, false);
						}
					}
				}
			}

			private boolean validDBPath(String dbPath, String db)
			{
				String[] files = (new File(dbPath)).list();
				for (String f : files)
				{
					if (f.indexOf(db) > -1) { return true; }
				}
				JOptionPane.showMessageDialog(new JFrame(), "The database " + db
						+ " does not exist in the path specified, please follow the following steps to download the blast correctly.", "Error!",
						JOptionPane.ERROR_MESSAGE);
				return false;
			}

			private void viewPredictionTab()
			{
				boolean viewPrediction = !"".equals(txtBlastPath.getText().trim()) && !"".equals(txtNRDB.getText().trim())
						&& !"".equals(txtCDD_DB.getText().trim());
				tabbedPane.setEnabledAt(2, viewPrediction);

			}

			private boolean validateBlastPath(String blastDirectory)
			{
				boolean valid = false;
				boolean rpsblastExist = false;
				boolean psiblastExist = false;

				String[] blastFiles = UtilDirectory.getDirectoryChildren(blastDirectory, ".exe");
				for (String file : blastFiles)
				{
					if (file.equals("rpsblast.exe"))
					{
						rpsblastExist = true;
					}
					if (file.equals("psiblast.exe"))
					{
						psiblastExist = true;
					}
				}

				if (!rpsblastExist)
				{
					JOptionPane
							.showMessageDialog(
									new JFrame(),
									"The rpsblast.exe is not exist in the path specified, please follow the following steps to download the blast correctly.",
									"Error!", JOptionPane.ERROR_MESSAGE);
					return false;
				}

				if (!psiblastExist)
				{
					JOptionPane
							.showMessageDialog(
									new JFrame(),
									"The psiblast.exe is not exist in the path specified, please follow the following steps to download the blast correctly.",
									"Error!", JOptionPane.ERROR_MESSAGE);
					return false;
				}

				valid = rpsblastExist && psiblastExist;

				return valid;
			}
		};

		button.addActionListener(blastBrowse);
		button_1.addActionListener(blastBrowse);
		button_2.addActionListener(blastBrowse);

		GroupLayout gl_panel_7 = new GroupLayout(panel_7);
		gl_panel_7.setHorizontalGroup(gl_panel_7
				.createParallelGroup(Alignment.TRAILING)
				.addGap(0, 632, Short.MAX_VALUE)
				.addGroup(
						gl_panel_7.createSequentialGroup().addComponent(txtBlastPath, GroupLayout.DEFAULT_SIZE, 555, Short.MAX_VALUE)
								.addPreferredGap(ComponentPlacement.RELATED).addComponent(button)));
		gl_panel_7.setVerticalGroup(gl_panel_7
				.createParallelGroup(Alignment.LEADING)
				.addGap(0, 31, Short.MAX_VALUE)
				.addGroup(
						gl_panel_7
								.createSequentialGroup()
								.addGroup(
										gl_panel_7.createParallelGroup(Alignment.BASELINE)
												.addComponent(txtBlastPath, GroupLayout.PREFERRED_SIZE, 28, GroupLayout.PREFERRED_SIZE)
												.addComponent(button)).addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)));
		panel_7.setLayout(gl_panel_7);

		JLabel lblHowToInstall = new JLabel("How to install BLAST");
		lblHowToInstall.setHorizontalAlignment(SwingConstants.CENTER);
		lblHowToInstall.setFont(new Font("Andalus", Font.BOLD, 15));

		JScrollPane scrollPane_1 = new JScrollPane();

		JScrollPane scrollPane_2 = new JScrollPane();
		scrollPane_2.setViewportBorder(new EtchedBorder(EtchedBorder.LOWERED, Color.LIGHT_GRAY, Color.GREEN));

		JLabel lblEnterThePath_1 = new JLabel("Enter the path of NR.00 database:");
		lblEnterThePath_1.setFont(new Font("Times New Roman", Font.BOLD, 12));

		JPanel panel_1 = new JPanel();
		panel_1.setForeground(Color.GREEN);
		panel_1.setBorder(new EtchedBorder(EtchedBorder.LOWERED, Color.LIGHT_GRAY, Color.GREEN));

		GroupLayout gl_panel_1 = new GroupLayout(panel_1);
		gl_panel_1.setHorizontalGroup(gl_panel_1
				.createParallelGroup(Alignment.TRAILING)
				.addGap(0, 632, Short.MAX_VALUE)
				.addGroup(
						gl_panel_1.createSequentialGroup().addComponent(txtNRDB, GroupLayout.DEFAULT_SIZE, 555, Short.MAX_VALUE)
								.addPreferredGap(ComponentPlacement.RELATED).addComponent(button_1)));
		gl_panel_1.setVerticalGroup(gl_panel_1
				.createParallelGroup(Alignment.LEADING)
				.addGap(0, 31, Short.MAX_VALUE)
				.addGroup(
						gl_panel_1
								.createSequentialGroup()
								.addGroup(
										gl_panel_1.createParallelGroup(Alignment.BASELINE)
												.addComponent(txtNRDB, GroupLayout.PREFERRED_SIZE, 28, GroupLayout.PREFERRED_SIZE)
												.addComponent(button_1)).addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)));
		panel_1.setLayout(gl_panel_1);

		JLabel lblEnterThePath_2 = new JLabel("Enter the path of CDD database:");
		lblEnterThePath_2.setFont(new Font("Times New Roman", Font.BOLD, 12));

		JPanel panel_4 = new JPanel();
		panel_4.setForeground(Color.GREEN);
		panel_4.setBorder(new EtchedBorder(EtchedBorder.LOWERED, Color.LIGHT_GRAY, Color.GREEN));

		GroupLayout gl_panel_4 = new GroupLayout(panel_4);
		gl_panel_4.setHorizontalGroup(gl_panel_4
				.createParallelGroup(Alignment.TRAILING)
				.addGap(0, 632, Short.MAX_VALUE)
				.addGap(0, 632, Short.MAX_VALUE)
				.addGroup(
						gl_panel_4.createSequentialGroup().addComponent(txtCDD_DB, GroupLayout.DEFAULT_SIZE, 555, Short.MAX_VALUE)
								.addPreferredGap(ComponentPlacement.RELATED).addComponent(button_2)));
		gl_panel_4.setVerticalGroup(gl_panel_4
				.createParallelGroup(Alignment.LEADING)
				.addGap(0, 31, Short.MAX_VALUE)
				.addGap(0, 31, Short.MAX_VALUE)
				.addGroup(
						gl_panel_4
								.createSequentialGroup()
								.addGroup(
										gl_panel_4.createParallelGroup(Alignment.BASELINE)
												.addComponent(txtCDD_DB, GroupLayout.PREFERRED_SIZE, 28, GroupLayout.PREFERRED_SIZE)
												.addComponent(button_2)).addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)));
		panel_4.setLayout(gl_panel_4);
		GroupLayout gl_panel = new GroupLayout(panel);
		gl_panel.setHorizontalGroup(gl_panel.createParallelGroup(Alignment.TRAILING).addGroup(
				gl_panel.createSequentialGroup()
						.addContainerGap()
						.addGroup(
								gl_panel.createParallelGroup(Alignment.LEADING)
										.addGroup(
												gl_panel.createSequentialGroup()
														.addComponent(scrollPane_2, GroupLayout.PREFERRED_SIZE, 635, GroupLayout.PREFERRED_SIZE)
														.addPreferredGap(ComponentPlacement.UNRELATED)
														.addComponent(scrollPane_1, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE,
																GroupLayout.PREFERRED_SIZE))
										.addComponent(lblEnterThePath, GroupLayout.PREFERRED_SIZE, 632, GroupLayout.PREFERRED_SIZE)
										.addComponent(panel_7, GroupLayout.PREFERRED_SIZE, 632, GroupLayout.PREFERRED_SIZE)
										.addComponent(lblEnterThePath_1, GroupLayout.PREFERRED_SIZE, 632, GroupLayout.PREFERRED_SIZE)
										.addComponent(panel_1, GroupLayout.PREFERRED_SIZE, 632, GroupLayout.PREFERRED_SIZE)
										.addComponent(lblEnterThePath_2, GroupLayout.PREFERRED_SIZE, 632, GroupLayout.PREFERRED_SIZE)
										.addComponent(panel_4, GroupLayout.PREFERRED_SIZE, 632, GroupLayout.PREFERRED_SIZE)
										.addComponent(lblHowToInstall, GroupLayout.PREFERRED_SIZE, 632, GroupLayout.PREFERRED_SIZE))
						.addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)));
		gl_panel.setVerticalGroup(gl_panel.createParallelGroup(Alignment.LEADING).addGroup(
				gl_panel.createSequentialGroup()
						.addContainerGap()
						.addComponent(lblEnterThePath)
						.addPreferredGap(ComponentPlacement.RELATED)
						.addComponent(panel_7, GroupLayout.PREFERRED_SIZE, 31, GroupLayout.PREFERRED_SIZE)
						.addPreferredGap(ComponentPlacement.RELATED)
						.addComponent(lblEnterThePath_1)
						.addPreferredGap(ComponentPlacement.RELATED)
						.addComponent(panel_1, GroupLayout.PREFERRED_SIZE, 31, GroupLayout.PREFERRED_SIZE)
						.addPreferredGap(ComponentPlacement.RELATED)
						.addGroup(
								gl_panel.createParallelGroup(Alignment.TRAILING)
										.addGroup(
												Alignment.LEADING,
												gl_panel.createSequentialGroup()
														.addGap(140)
														.addComponent(scrollPane_1, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE,
																GroupLayout.PREFERRED_SIZE))
										.addGroup(
												gl_panel.createSequentialGroup().addGap(6).addComponent(lblEnterThePath_2)
														.addPreferredGap(ComponentPlacement.RELATED)
														.addComponent(panel_4, GroupLayout.PREFERRED_SIZE, 31, GroupLayout.PREFERRED_SIZE)
														.addPreferredGap(ComponentPlacement.RELATED)
														.addComponent(lblHowToInstall, GroupLayout.PREFERRED_SIZE, 17, Short.MAX_VALUE).addGap(1)
														.addComponent(scrollPane_2, GroupLayout.PREFERRED_SIZE, 273, GroupLayout.PREFERRED_SIZE)))
						.addContainerGap()));

		JTextArea textArea = new JTextArea();
		textArea.setText("Go to Blast site\r\n\r\ndownload\r\n\r\ndownload database\r\n\r\nTODO: Complete");
		scrollPane_2.setViewportView(textArea);
		panel.setLayout(gl_panel);

		tabbedPane.addTab("Prediction", null, tab_Prediction, null);
		tabbedPane.setEnabledAt(2, false);

		JLabel lblNewLabel_1 = new JLabel("Query protein(s) in FASTA format:");
		lblNewLabel_1.setFont(new Font("Times New Roman", Font.BOLD, 12));

		JScrollPane scrollPane = new JScrollPane();
		scrollPane.setViewportBorder(new EtchedBorder(EtchedBorder.LOWERED, Color.LIGHT_GRAY, Color.GREEN));

		JLabel lblUploadAFile = new JLabel("Upload a file in FASTA format directly from your local disk:");
		lblUploadAFile.setFont(new Font("Times New Roman", Font.BOLD, 12));

		JPanel panel_2 = new JPanel();
		panel_2.setBorder(new EtchedBorder(EtchedBorder.LOWERED, Color.LIGHT_GRAY, Color.GREEN));
		panel_2.setForeground(Color.GREEN);

		JLabel lblPredictionApproach = new JLabel("Prediction Approach:");
		lblPredictionApproach.setFont(new Font("Times New Roman", Font.BOLD, 12));

		final JRadioButton rd_PSSM = new JRadioButton("PSSM (Position Specific Scoring Matrix)");
		rd_PSSM.setMnemonic('1');

		final JRadioButton rd_CD = new JRadioButton("CD (Conserved Domains)");
		rd_CD.setMnemonic('2');

		final JRadioButton rdVirulentCD = new JRadioButton("Virulent-CD (PSSM + CD)");
		rdVirulentCD.setMnemonic('3');
		rdVirulentCD.setSelected(true);

		group = new ButtonGroup();
		group.add(rd_PSSM);
		group.add(rd_CD);
		group.add(rdVirulentCD);

		JLabel lblSpecificity = new JLabel("Specificity:");
		lblSpecificity.setFont(new Font("Times New Roman", Font.BOLD, 12));

		final JComboBox comboSpecificity = new JComboBox();
		comboSpecificity.setFont(new Font("Times New Roman", Font.PLAIN, 11));
		comboSpecificity.setModel(new DefaultComboBoxModel(new String[]
		{ "65", "70", "75", "80", "85", "90", "95" }));
		comboSpecificity.setSelectedIndex(3);

		JPanel panel_3 = new JPanel();
		panel_3.setBorder(new EtchedBorder(EtchedBorder.LOWERED, Color.LIGHT_GRAY, Color.GREEN));

		final JProgressBar progressBar = new JProgressBar();
		GroupLayout gl_tab_Prediction = new GroupLayout(tab_Prediction);
		gl_tab_Prediction
				.setHorizontalGroup(gl_tab_Prediction
						.createParallelGroup(Alignment.LEADING)
						.addGroup(
								gl_tab_Prediction
										.createSequentialGroup()
										.addGroup(
												gl_tab_Prediction
														.createParallelGroup(Alignment.LEADING)
														.addGroup(
																gl_tab_Prediction
																		.createSequentialGroup()
																		.addContainerGap()
																		.addGroup(
																				gl_tab_Prediction
																						.createParallelGroup(Alignment.LEADING)
																						.addComponent(progressBar, Alignment.TRAILING,
																								GroupLayout.DEFAULT_SIZE, 632, Short.MAX_VALUE)
																						.addComponent(lblNewLabel_1, GroupLayout.DEFAULT_SIZE, 632,
																								Short.MAX_VALUE)
																						.addComponent(scrollPane, GroupLayout.DEFAULT_SIZE, 632,
																								Short.MAX_VALUE)))
														.addGroup(
																gl_tab_Prediction
																		.createSequentialGroup()
																		.addGap(195)
																		.addComponent(panel_3, GroupLayout.PREFERRED_SIZE, 236,
																				GroupLayout.PREFERRED_SIZE))
														.addGroup(
																gl_tab_Prediction
																		.createSequentialGroup()
																		.addContainerGap()
																		.addGroup(
																				gl_tab_Prediction
																						.createParallelGroup(Alignment.LEADING)
																						.addComponent(lblPredictionApproach,
																								GroupLayout.DEFAULT_SIZE, 632, Short.MAX_VALUE)
																						.addGroup(
																								gl_tab_Prediction
																										.createSequentialGroup()
																										.addGap(10)
																										.addGroup(
																												gl_tab_Prediction
																														.createParallelGroup(
																																Alignment.LEADING)
																														.addComponent(
																																rd_CD,
																																GroupLayout.PREFERRED_SIZE,
																																209,
																																GroupLayout.PREFERRED_SIZE)
																														.addComponent(rd_PSSM)
																														.addComponent(
																																rdVirulentCD,
																																GroupLayout.PREFERRED_SIZE,
																																209,
																																GroupLayout.PREFERRED_SIZE)))
																						.addGroup(
																								gl_tab_Prediction
																										.createSequentialGroup()
																										.addComponent(lblSpecificity,
																												GroupLayout.PREFERRED_SIZE, 67,
																												GroupLayout.PREFERRED_SIZE)
																										.addPreferredGap(ComponentPlacement.RELATED)
																										.addComponent(comboSpecificity,
																												GroupLayout.PREFERRED_SIZE,
																												GroupLayout.DEFAULT_SIZE,
																												GroupLayout.PREFERRED_SIZE))))
														.addGroup(
																Alignment.TRAILING,
																gl_tab_Prediction
																		.createSequentialGroup()
																		.addContainerGap()
																		.addGroup(
																				gl_tab_Prediction
																						.createParallelGroup(Alignment.LEADING)
																						.addComponent(lblUploadAFile, GroupLayout.DEFAULT_SIZE, 632,
																								Short.MAX_VALUE)
																						.addComponent(panel_2, GroupLayout.DEFAULT_SIZE, 632,
																								Short.MAX_VALUE)))).addContainerGap()));
		gl_tab_Prediction.setVerticalGroup(gl_tab_Prediction.createParallelGroup(Alignment.LEADING).addGroup(
				gl_tab_Prediction
						.createSequentialGroup()
						.addContainerGap()
						.addComponent(lblNewLabel_1)
						.addPreferredGap(ComponentPlacement.RELATED)
						.addComponent(scrollPane, GroupLayout.DEFAULT_SIZE, 187, Short.MAX_VALUE)
						.addPreferredGap(ComponentPlacement.RELATED)
						.addComponent(lblUploadAFile)
						.addPreferredGap(ComponentPlacement.RELATED)
						.addComponent(panel_2, GroupLayout.PREFERRED_SIZE, 31, GroupLayout.PREFERRED_SIZE)
						.addPreferredGap(ComponentPlacement.RELATED)
						.addComponent(lblPredictionApproach)
						.addPreferredGap(ComponentPlacement.RELATED)
						.addComponent(rd_PSSM)
						.addPreferredGap(ComponentPlacement.RELATED)
						.addComponent(rd_CD)
						.addPreferredGap(ComponentPlacement.RELATED)
						.addComponent(rdVirulentCD)
						.addPreferredGap(ComponentPlacement.RELATED)
						.addGroup(
								gl_tab_Prediction
										.createParallelGroup(Alignment.BASELINE)
										.addComponent(lblSpecificity)
										.addComponent(comboSpecificity, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE,
												GroupLayout.PREFERRED_SIZE)).addPreferredGap(ComponentPlacement.RELATED)
						.addComponent(panel_3, GroupLayout.PREFERRED_SIZE, 50, GroupLayout.PREFERRED_SIZE)
						.addPreferredGap(ComponentPlacement.RELATED)
						.addComponent(progressBar, GroupLayout.PREFERRED_SIZE, 24, GroupLayout.PREFERRED_SIZE).addContainerGap()));

		final JButton btnSubmit = new JButton("Submit");
		btnSubmit.addActionListener(new ActionListener()
		{
			public void actionPerformed(ActionEvent arg0)
			{
				try
				{
					// 1. Load Configuration
					final Configuration config = Configuration.getInstance();
					config.loadConfiguration("./Virulent-CD");
					config.set("blast", txtBlastPath.getText().trim());
					config.set("blast.db.nr", txtNRDB.getText().trim());
					config.set("blast.db.cd", txtCDD_DB.getText().trim());

					// 2. Create The request form
					final RequestForm form = getRequestForm();

					// 3. Validate Request Form
					if (form == null) { return; }
					ArrayList<String> errorMessages = form.validate();
					if (errorMessages.size() > 0)
					{
						viewErrors(errorMessages);
					}
					else
					{
						new Thread()
						{
							public void run()
							{
								btnSubmit.setEnabled(false);
								tabbedPane.setEnabledAt(3, false);
								progressBar.setString("Prediction in progress...");
								progressBar.setIndeterminate(true);
								// 4. Pass parameters to model
								Prediction model;
								try
								{
									model = Prediction.getPrediction();

									// 5. Get the prediction results
									PredictionForm predForm = new PredictionForm(form.getProteinList(), form.getPredictionApproach().getFeatures(),
											form.getPredictionApproach().getClassifier(), form.getSpecificity(), config.get("class.1"), config
													.get("class.2"));
									
									ArrayList<PredictionResult> predictionResult = model.predict(predForm);

									// 6. view the prediction result in the
									// table
									ArrayList<String> errorMessages = form.validate();
									if (errorMessages.size() > 0)
									{
										viewErrors(errorMessages);
									}
									else
									{
										// / fill the table with prediction
										// results
										String app = "";
										if (rd_PSSM.isSelected())
											app = "PSSM";
										else if (rd_CD.isSelected())
											app = "CD";
										else if (rdVirulentCD.isSelected()) app = "Virulent-CD";

										for (PredictionResult result : predictionResult)
										{
											String[] row = new String[]
											{ result.getProtienID(), app, comboSpecificity.getSelectedItem().toString(), result.getPredictionScore(),
													result.getPredictionClass() };
											tableModel.addRow(row);
										}
									}
									btnSubmit.setEnabled(true);
									tabbedPane.setEnabledAt(3, true);
									progressBar.setIndeterminate(false);
									JOptionPane.showMessageDialog(new JFrame(), "Virulent-CD successfully predicted your sequence!", "Virulent-CD",
											JOptionPane.INFORMATION_MESSAGE);
									tabbedPane.setSelectedIndex(3);
								}

								catch (Exception e)
								{
									JOptionPane.showMessageDialog(new JFrame(), "Internal Error!\n" + e.getMessage(), "Error!",
											JOptionPane.ERROR_MESSAGE);
									btnSubmit.setEnabled(true);
									e.printStackTrace();
									progressBar.setIndeterminate(false);
								}
							};
						}.start();
					}
				}
				catch (IOException e)
				{
					JOptionPane.showMessageDialog(new JFrame(), "Internal Error!\n" + e.getMessage(), "Error!", JOptionPane.ERROR_MESSAGE);
					e.printStackTrace();
					progressBar.setIndeterminate(false);
				}
				catch (Exception e)
				{
					JOptionPane.showMessageDialog(new JFrame(), "Internal Error!\n" + e.getMessage(), "Error!", JOptionPane.ERROR_MESSAGE);
					e.printStackTrace();
					progressBar.setIndeterminate(false);
				}
			}

			private void viewErrors(ArrayList<String> errorMessages)
			{
				StringBuffer errorList = new StringBuffer("The Virulent-CD server has encountered the following errors:\n");
				for (String error : errorMessages)
				{
					errorList.append(error).append("\n");
				}

				// show the error messages
				JOptionPane.showMessageDialog(new JFrame(), errorList.toString(), "Error!", JOptionPane.ERROR_MESSAGE);

			}

			private RequestForm getRequestForm() throws Exception
			{
				RequestForm form;
				
				// set protein sequence
				String proteinSequence = proteins_paste.getText().trim();
				String fastaFilePath = txtFastaFile.getText().trim();
				if ("".equals(proteinSequence) && "".equals(fastaFilePath))
				{
					JOptionPane.showMessageDialog(new JFrame(), "Please enter one of more proteins in FASTA format.", "Error!",
							JOptionPane.ERROR_MESSAGE);
					return null;
				}
				else
				{
					if (!"".equals(proteinSequence))
					{
						proteinSequence = proteinSequence.toUpperCase();
					}
					else if (!"".equals(fastaFilePath))
					{

						File fastaFile = new File(fastaFilePath);
						if (fastaFile.exists())
						{
							try
							{
								String fileContent = UtilDirectory.readFileToEnd(fastaFilePath);
								proteinSequence = fileContent;
							}
							catch (IOException e)
							{
								JOptionPane.showMessageDialog(new JFrame(), "Unknown Error!", "Error!", JOptionPane.ERROR_MESSAGE);
								e.printStackTrace();
								return null;
							}
						}
						else
						{
							JOptionPane.showMessageDialog(new JFrame(),
									"The FASTA file path you specified is not correct, Please enter one of more proteins in FASTA format.", "Error!",
									JOptionPane.ERROR_MESSAGE);
							return null;
						}
					}
				}
				// set prediction approach
				String app = "";
				if (rd_PSSM.isSelected())
					app = "PSSM";
				else if (rd_CD.isSelected())
					app = "CD";
				else if (rdVirulentCD.isSelected()) app = "PSSM,CD";

				// set Specificity
				double specificity = Double.parseDouble(comboSpecificity.getSelectedItem().toString().trim()) / (double) 100; 
				
				form = new RequestForm(proteinSequence, app, specificity, null);
				
				return form;

			}
		});
		btnSubmit.setFont(new Font("Times New Roman", Font.BOLD, 14));

		JButton btnClearData = new JButton("Clear Data");
		btnClearData.setFont(new Font("Times New Roman", Font.BOLD, 14));
		btnClearData.addActionListener(new ActionListener()
		{
			public void actionPerformed(ActionEvent e)
			{
				proteins_paste.setText("");
				txtFastaFile.setText("");
				rdVirulentCD.setSelected(true);
				comboSpecificity.setSelectedIndex(3);
			}
		});
		GroupLayout gl_panel_3 = new GroupLayout(panel_3);
		gl_panel_3.setHorizontalGroup(gl_panel_3.createParallelGroup(Alignment.LEADING).addGroup(
				gl_panel_3.createSequentialGroup().addGap(27).addComponent(btnClearData).addPreferredGap(ComponentPlacement.RELATED)
						.addComponent(btnSubmit).addContainerGap(35, Short.MAX_VALUE)));
		gl_panel_3.setVerticalGroup(gl_panel_3.createParallelGroup(Alignment.LEADING).addGroup(
				gl_panel_3.createSequentialGroup().addContainerGap()
						.addGroup(gl_panel_3.createParallelGroup(Alignment.BASELINE).addComponent(btnSubmit).addComponent(btnClearData))
						.addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)));
		panel_3.setLayout(gl_panel_3);

		txtFastaFile = new JTextField();
		txtFastaFile.setColumns(10);
		txtFastaFile.setEditable(false);

		JButton btnBrowse = new JButton("Browse");
		btnBrowse.addActionListener(new ActionListener()
		{
			public void actionPerformed(ActionEvent e)
			{

				// Create a file chooser
				final JFileChooser fc = new JFileChooser();
				fc.setDialogTitle("Choose a file in FASTA format from your disk");
				fc.removeChoosableFileFilter(fc.getFileFilter());
				fc.setFileFilter(new FileFilter()
				{

					@Override
					public String getDescription()
					{
						// TODO Auto-generated method stub
						return "*.fasta";
					}

					@Override
					public boolean accept(File f)
					{
						return f.isFile() && f.getName().toLowerCase().endsWith(".fasta");
					}
				});
				int returnVal = fc.showOpenDialog(VirulentCD.this);
				if (returnVal == JFileChooser.APPROVE_OPTION)
				{
					File file = fc.getSelectedFile();
					txtFastaFile.setText(file.getPath());
				}

			}
		});
		GroupLayout gl_panel_2 = new GroupLayout(panel_2);
		gl_panel_2.setHorizontalGroup(gl_panel_2.createParallelGroup(Alignment.LEADING).addGroup(
				Alignment.TRAILING,
				gl_panel_2.createSequentialGroup().addComponent(txtFastaFile, GroupLayout.DEFAULT_SIZE, 524, Short.MAX_VALUE)
						.addPreferredGap(ComponentPlacement.RELATED).addComponent(btnBrowse)));
		gl_panel_2.setVerticalGroup(gl_panel_2.createParallelGroup(Alignment.LEADING).addGroup(
				gl_panel_2
						.createSequentialGroup()
						.addGroup(
								gl_panel_2.createParallelGroup(Alignment.BASELINE)
										.addComponent(txtFastaFile, GroupLayout.PREFERRED_SIZE, 28, GroupLayout.PREFERRED_SIZE)
										.addComponent(btnBrowse)).addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)));
		panel_2.setLayout(gl_panel_2);

		scrollPane.setViewportView(proteins_paste);
		proteins_paste.setFont(new Font("Times New Roman", Font.PLAIN, 16));
		proteins_paste.setLineWrap(true);
		proteins_paste.setWrapStyleWord(true);
		tab_Prediction.setLayout(gl_tab_Prediction);

		JPanel tab_Results = new JPanel();
		tabbedPane.addTab("Prediction Results", null, tab_Results, null);
		tabbedPane.setEnabledAt(3, false);

		JLabel lblThankYouFor = new JLabel("Thank you for using Virulent-CD server");
		lblThankYouFor.setFont(new Font("Andalus", Font.BOLD | Font.ITALIC, 30));
		lblThankYouFor.setHorizontalAlignment(SwingConstants.CENTER);

		JLabel lblPredictionResultsIn = new JLabel("Prediction results in the table below:");
		lblPredictionResultsIn.setFont(new Font("Times New Roman", Font.BOLD, 20));

		JPanel panel_5 = new JPanel();
		panel_5.setBorder(new EtchedBorder(EtchedBorder.LOWERED, Color.LIGHT_GRAY, Color.GREEN));

		JButton btnBack = new JButton("Back");
		btnBack.addActionListener(new ActionListener()
		{
			public void actionPerformed(ActionEvent arg0)
			{
				tabbedPane.setSelectedIndex(2);
			}
		});
		btnBack.setFont(new Font("Times New Roman", Font.BOLD, 14));

		JButton btnCloseVirulentcd = new JButton("Close");
		btnCloseVirulentcd.addActionListener(new ActionListener()
		{
			public void actionPerformed(ActionEvent arg0)
			{
				JOptionPane.showMessageDialog(new JFrame(), "Thank you for using Virulent-CD!", "Virulent-CD", JOptionPane.INFORMATION_MESSAGE);
				System.exit(0);
			}
		});
		btnCloseVirulentcd.setFont(new Font("Times New Roman", Font.BOLD, 14));
		GroupLayout gl_panel_5 = new GroupLayout(panel_5);
		gl_panel_5.setHorizontalGroup(gl_panel_5.createParallelGroup(Alignment.LEADING).addGroup(
				gl_panel_5.createSequentialGroup().addGap(56).addComponent(btnBack).addPreferredGap(ComponentPlacement.RELATED)
						.addComponent(btnCloseVirulentcd).addContainerGap(56, Short.MAX_VALUE)));
		gl_panel_5.setVerticalGroup(gl_panel_5.createParallelGroup(Alignment.LEADING).addGroup(
				Alignment.TRAILING,
				gl_panel_5.createSequentialGroup().addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
						.addGroup(gl_panel_5.createParallelGroup(Alignment.BASELINE).addComponent(btnBack).addComponent(btnCloseVirulentcd))
						.addContainerGap()));
		panel_5.setLayout(gl_panel_5);

		JScrollPane scrollPane_3 = new JScrollPane();
		GroupLayout gl_tab_Results = new GroupLayout(tab_Results);
		gl_tab_Results.setHorizontalGroup(gl_tab_Results.createParallelGroup(Alignment.LEADING)
				.addGroup(
						Alignment.TRAILING,
						gl_tab_Results
								.createSequentialGroup()
								.addGroup(
										gl_tab_Results
												.createParallelGroup(Alignment.TRAILING)
												.addGroup(
														Alignment.LEADING,
														gl_tab_Results.createSequentialGroup().addContainerGap()
																.addComponent(scrollPane_3, GroupLayout.DEFAULT_SIZE, 632, Short.MAX_VALUE))
												.addGroup(
														Alignment.LEADING,
														gl_tab_Results
																.createSequentialGroup()
																.addContainerGap()
																.addGroup(
																		gl_tab_Results
																				.createParallelGroup(Alignment.LEADING)
																				.addComponent(lblPredictionResultsIn, GroupLayout.PREFERRED_SIZE,
																						444, GroupLayout.PREFERRED_SIZE)
																				.addComponent(lblThankYouFor, GroupLayout.DEFAULT_SIZE, 632,
																						Short.MAX_VALUE)))
												.addGroup(
														Alignment.LEADING,
														gl_tab_Results
																.createSequentialGroup()
																.addGap(199)
																.addComponent(panel_5, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE,
																		GroupLayout.PREFERRED_SIZE))).addContainerGap()));
		gl_tab_Results.setVerticalGroup(gl_tab_Results.createParallelGroup(Alignment.LEADING).addGroup(
				gl_tab_Results.createSequentialGroup().addContainerGap()
						.addComponent(lblThankYouFor, GroupLayout.PREFERRED_SIZE, 35, GroupLayout.PREFERRED_SIZE)
						.addPreferredGap(ComponentPlacement.RELATED)
						.addComponent(lblPredictionResultsIn, GroupLayout.PREFERRED_SIZE, 35, GroupLayout.PREFERRED_SIZE)
						.addPreferredGap(ComponentPlacement.RELATED).addComponent(scrollPane_3, GroupLayout.DEFAULT_SIZE, 323, Short.MAX_VALUE)
						.addPreferredGap(ComponentPlacement.RELATED)
						.addComponent(panel_5, GroupLayout.PREFERRED_SIZE, 51, GroupLayout.PREFERRED_SIZE).addContainerGap()));

		table = new JTable();
		tableModel = new DefaultTableModel(new Object[][] {}, new String[]
		{ "Protein Name", "Approach", "Specificity", "Prediction Score", "Prediction Result" })
		{
			Class[] columnTypes = new Class[]
			{ String.class, String.class, String.class, String.class, String.class };

			public Class getColumnClass(int columnIndex)
			{
				return columnTypes[columnIndex];
			}

		};
		table.setEnabled(false);

		table.setModel(tableModel);
		table.getColumnModel().getColumn(1).setPreferredWidth(118);
		table.getColumnModel().getColumn(2).setPreferredWidth(100);
		table.getColumnModel().getColumn(3).setPreferredWidth(111);
		table.getColumnModel().getColumn(4).setPreferredWidth(108);
		table.setSurrendersFocusOnKeystroke(true);
		table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
		table.setFillsViewportHeight(true);
		table.setCellSelectionEnabled(true);
		table.setBorder(new EtchedBorder(EtchedBorder.LOWERED, Color.LIGHT_GRAY, Color.GREEN));
		scrollPane_3.setViewportView(table);
		tab_Results.setLayout(gl_tab_Results);
	}
}
